
export function createStore(reducer, enhancer){
    if(enhancer){
        return enhancer(createStore)(reducer)
    }
    let currentState = {}
    let currentListeners = []
    function getState(){
        return currentState
    }
    function subscribe(listener){
        currentListeners.push(listener)
    }
    function dispatch(action){
        currentState = reducer(currentState, action)
        currentListeners.forEach(item => item())
        return action
    }
    dispatch({type: '@/wjj/miniRedux'})
    return { getState, subscribe, dispatch }
}

export function applyMiddleware(middlewares){
    return createStore => (...args) => {
        const store = createStore(...args)
        let dispatch = store.dispatch
        const midApi = {
            getState: store.getState,
            //注意点： 这里dispatch是调用compose函数后增强的dispatch
            dispatch: (...args) => dispatch(...args)
        }
        const middlewareChain = middlewares.map(middleware => middleware(midApi))
        dispatch = compose(...middlewareChain)(dispatch)
        //dispatch = middleware(midApi)(dispatch)
        return {
            ...store,
            dispatch
        }
    }
}

export function compose(...funs){
    if(funs.length === 0) return arg => arg
    if(funs.length === 1) return funs[0]
    return funs.reduce((ret, item) => {
        return (...args) => {
            //中间件作用顺序从左到右
            return ret(item(...args))
            //中间作用顺序从右到左
            //return item(ret(...args))
        }
    })
}

function bindActionCreator(creator, dispatch){
    return (...args) => dispatch(creator(...args))
}

export function bindActionCreators(creators, dispatch){
    //let bound = {}
    //Object.keys(creators).forEach(v => {
    //    let creator = creators[v]
    //    bound[v] = bindActionCreator(creator, dispatch)
    //})
    //return bound
    return Object.keys(creators).reduce((result, current) => {
        result[current] = bindActionCreator(creators[current], dispatch)
        return result
    }, {})
}